<?php

namespace app\common\library;

use think\Exception;

/**
 * 小程序订阅消息推送工具类
 */
class MiniProgramMessage
{
    protected $appId;
    protected $appSecret;
    protected $accessToken;

    public function __construct()
    {
        $this->appId = config('wechat.miniprogram.appid') ?: '';
        $this->appSecret = config('wechat.miniprogram.secret') ?: '';
    }

    /**
     * 获取访问令牌
     */
    protected function getAccessToken()
    {
        $cacheKey = 'miniprogram_access_token';
        $accessToken = cache($cacheKey);
        
        if ($accessToken && $accessToken['expire'] > time()) {
            return $accessToken['token'];
        }

        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appId}&secret={$this->appSecret}";
        
        $response = $this->httpGet($url);
        $result = json_decode($response, true);
        
        if (isset($result['access_token'])) {
            $accessToken = [
                'token' => $result['access_token'],
                'expire' => time() + $result['expires_in'] - 300
            ];
            
            cache($cacheKey, $accessToken, $result['expires_in'] - 300);
            return $accessToken['token'];
        } else {
            throw new Exception('获取小程序access_token失败：' . json_encode($result));
        }
    }

    /**
     * 发送订阅消息
     */
    public function sendSubscribeMessage($openid, $templateId, $data, $page = 'pages/tasks/tasks')
    {
        if (empty($openid)) {
            throw new Exception('openid不能为空');
        }

        $accessToken = $this->getAccessToken();
        $apiUrl = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={$accessToken}";
        
        $message = [
            'touser' => $openid,
            'template_id' => $templateId,
            'page' => $page,
            'data' => $data
        ];
        
        $response = $this->httpPost($apiUrl, json_encode($message));
        $result = json_decode($response, true);
        
        if ($result['errcode'] == 0) {
            return true;
        } else {
            throw new Exception('发送订阅消息失败：' . $result['errmsg']);
        }
    }

    /**
     * 发送分工通知订阅消息
     */
    public function sendAllocationNotification($openid, $allocationData)
    {
        // 订阅消息模板ID，需要在小程序管理后台申请
        $templateId = config('wechat.miniprogram.template_id.allocation') ?: '';
        
        if (empty($templateId)) {
            \think\Log::warning('未配置分工通知订阅消息模板ID');
            return false;
        }
        
        $data = [
            'thing1' => [ // 订单编号
                'value' => $allocationData['order_no']
            ],
            'thing2' => [ // 产品信息
                'value' => $allocationData['product_name'] . ' - ' . $allocationData['model_name']
            ],
            'thing3' => [ // 工序名称
                'value' => $allocationData['process_name']
            ],
            'number4' => [ // 任务数量
                'value' => $allocationData['quantity']
            ],
            'time5' => [ // 分配时间
                'value' => date('Y-m-d H:i:s')
            ]
        ];
        
        return $this->sendSubscribeMessage($openid, $templateId, $data, 'pages/tasks/tasks');
    }

    /**
     * 发送审核结果订阅消息
     */
    public function sendAuditNotification($openid, $auditData)
    {
        $templateId = config('wechat.miniprogram.template_id.audit') ?: '';
        
        if (empty($templateId)) {
            \think\Log::warning('未配置审核通知订阅消息模板ID');
            return false;
        }
        
        $statusText = $auditData['status'] == 1 ? '审核通过' : '审核不通过';
        
        $data = [
            'thing1' => [ // 订单编号
                'value' => $auditData['order_no']
            ],
            'thing2' => [ // 产品名称
                'value' => $auditData['product_name']
            ],
            'phrase3' => [ // 审核结果
                'value' => $statusText
            ],
            'number4' => [ // 报工数量
                'value' => $auditData['quantity']
            ],
            'time5' => [ // 审核时间
                'value' => date('Y-m-d H:i:s')
            ]
        ];
        
        return $this->sendSubscribeMessage($openid, $templateId, $data, 'pages/records/records');
    }

    /**
     * 发送系统通知订阅消息
     */
    public function sendSystemNotification($openid, $systemData)
    {
        $templateId = config('wechat.miniprogram.template_id.system') ?: '';
        
        if (empty($templateId)) {
            \think\Log::warning('未配置系统通知订阅消息模板ID');
            return false;
        }
        
        $data = [
            'thing1' => [ // 通知标题
                'value' => $systemData['title'] ?? '系统通知'
            ],
            'thing2' => [ // 通知内容
                'value' => $systemData['content'] ?? ''
            ],
            'time3' => [ // 通知时间
                'value' => $systemData['time'] ?? date('Y-m-d H:i:s')
            ],
            'thing4' => [ // 备注信息
                'value' => $systemData['remark'] ?? ''
            ]
        ];
        
        return $this->sendSubscribeMessage($openid, $templateId, $data, 'pages/messages/messages');
    }

    /**
     * HTTP GET请求
     */
    protected function httpGet($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        
        $response = curl_exec($ch);
        curl_close($ch);
        
        return $response;
    }

    /**
     * HTTP POST请求
     */
    protected function httpPost($url, $data)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($data)
        ]);
        
        $response = curl_exec($ch);
        curl_close($ch);
        
        return $response;
    }
}
